﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Firefly.Framework.Graphics
{
    public class GraphicsService : IGraphicsDeviceService, IHasContent
    {
        private Game _game;

        public GraphicsDeviceManager GraphicsDeviceManager { get; private set; }
        public GraphicsDevice GraphicsDevice
        {
            get { return GraphicsDeviceManager.GraphicsDevice; }
        }
        public PresentationParameters PresentationParameters
        {
            get { return GraphicsDevice.PresentationParameters; }
        }
        public GraphicsDeviceCapabilities GraphicsDeviceCapabilities
        {
            get { return GraphicsDevice.GraphicsDeviceCapabilities; }
        }
        public SpriteBatch SpriteBatch { get; private set; }
        public RenderState RenderState
        {
            get { return GraphicsDevice.RenderState; }
        }
        public FillMode FillMode
        {
            get { return GraphicsDevice.RenderState.FillMode; }
            set { GraphicsDevice.RenderState.FillMode = value; }
        }
        public DepthStencilBuffer DepthStencilBuffer
        {
            get { return GraphicsDevice.DepthStencilBuffer; }
            set { GraphicsDevice.DepthStencilBuffer = value; }
        }
        public Viewport Viewport 
        { 
            get { return GraphicsDevice.Viewport; } 
        }
        public float AspectRatio 
        { 
            get { return Viewport.AspectRatio; } 
        }
        public IndexBuffer Indices
        {
            get { return GraphicsDevice.Indices; }
            set { GraphicsDevice.Indices = value; }
        }
        public VertexStreamCollection Vertices
        {
            get { return GraphicsDevice.Vertices; }
        }
        public VertexDeclaration VertexDeclaration
        {
            get { return GraphicsDevice.VertexDeclaration; }
            set { GraphicsDevice.VertexDeclaration = value; }
        }

        public void Initialize(Game game)
        {
            _game = game;
            GraphicsDeviceManager = new GraphicsDeviceManager(_game);
        }

        public void Clear(Color color)
        {
            GraphicsDevice.Clear(color);
        }

        public void ToggleFullScreen()
        {
            GraphicsDeviceManager.IsFullScreen = GraphicsDeviceManager.IsFullScreen ? GraphicsDeviceManager.IsFullScreen = false : GraphicsDeviceManager.IsFullScreen = true;
        }

        public void SetRenderTarget(int renderTargetIndex, RenderTarget2D renderTarget)
        {
            GraphicsDevice.SetRenderTarget(renderTargetIndex, renderTarget);
        }

        #region IGraphicsDeviceService Members

        public event EventHandler DeviceCreated;
        public event EventHandler DeviceDisposing;
        public event EventHandler DeviceReset;
        public event EventHandler DeviceResetting;

        #endregion

        #region IHasContent Members

        public void LoadContent()
        {
            SpriteBatch = new SpriteBatch(GraphicsDevice);
            VertexDeclaration = new VertexDeclaration(GraphicsDevice, VertexPosition.VertexElements);
        }

        public void UnloadContent()
        {
            SpriteBatch.Dispose();
            SpriteBatch = null;
        }

        #endregion

		#region Threadsafe Singleton
		
        public static GraphicsService Instance
        {
            get { return Nested._instance; }
        }

        private class Nested
        {
			internal static readonly GraphicsService _instance = new GraphicsService();
        
            static Nested() { }
        }

        private GraphicsService() { }
        
        #endregion
}
}
